home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
graphic
/
frasr182.zip
/
PARSER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-13
|
56KB
|
2,251 lines
/* Parser.c (C) 1990, Mark C. Peterson, CompuServe [70441,3353]
All rights reserved.
Code may be used in any program provided the author is credited
either during program execution or in the documentation. Source
code may be distributed only in combination with public domain or
shareware source code. Source code may be modified provided the
copyright notice and this message is left unchanged and all
modifications are clearly documented.
I would appreciate a copy of any work which incorporates this code,
however this is optional.
Mark C. Peterson
405-C Queen St. Suite #181
Southington, CT 06489
(203) 276-9721
*/
/* Chuck Ebbert (CompuServe [76306,1226] ) changed code marked 'CAE fp' */
/* for fast 387 floating-point math. See PARSERA.ASM and PARSERFP.C */
/* (13 Dec 1992.) */
/* */
/* Modified 12 July 1993 by CAE to fix crash when formula not found. */
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h> /* TIW 04-22-91 */
#include <time.h>
#include "mpmath.h"
#include "prototyp.h"
extern int CvtStk(void); /* CAE fp */
extern int Transparent3D; /* MCP 5-30-91 */
#ifdef WATCH_MP
double x1, y1, x2, y2;
#endif
MATH_TYPE MathType = D_MATH;
/* moved _LCMPLX and union ARg to mpmath.h -6-20-90 TIW */
/* PB 910417 added MAX_OPS and MAX_ARGS defines */
#define MAX_ARGS 100
#define MAX_OPS 250
struct PEND_OP {
void (far *f)(void);
int p;
};
/* CAE fp added MAX_STORES and LOADS */
#define MAX_STORES 125 /* at most only half the ops can be stores */
#define MAX_LOADS 200 /* and 80% can be loads */
/* PB 901103 made some of the following static for safety */
static struct PEND_OP far *o;
static void parser_allocate(void);
union Arg *Arg1, *Arg2;
/* PB 910417 removed unused "a" array */
/* CAE fp made some of the following non-static for PARSERA.ASM */
/* Some of these variables should be renamed for safety */
union Arg s[20], far * far *Store, far * far *Load; /* static CAE fp */
int StoPtr, LodPtr, OpPtr; /* static CAE fp */
struct fls { /* function, load, store pointers CAE fp */
void (near *function)(void);
union Arg near *operand;
};
extern struct fls far *pfls; /* init in parserfp.c CAE fp */
void (far * far *f)(void) = (void(far * far *)(void))0; /* static CAE fp */
unsigned vsp, LastOp; /* CAE fp made non-static */
static unsigned n, ErrPtr, posp, NextOp, InitN;
static int paren, SyntaxErr, ExpectingArg;
struct ConstArg far *v = (struct ConstArg far *)0; /* was static CAE fp */
int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp; /* was static CAE fp */
static int Delta16;
double fgLimit; /* TIW 05-04-91 */
static double fg;
static int ShiftBack; /* TIW 06-18-90 */
static int SetRandom; /* MCP 11-21-91 */
static int Randomized;
static unsigned long RandNum;
extern int bitshift;
extern int bitshiftless1;
extern int symmetry; /* symmetry flag for calcmand() */
extern double param[];
extern int debugflag; /* BDT for debugging */
extern char boxx[8192]; /* PB 4-9-91, good place for the formula string */
extern int row, col, overflow, cpu, fpu;
extern _CMPLX old, new;
extern double far *dx0, far *dy0;
extern long far *lx0, far *ly0; /* BDT moved these to FAR */
#ifndef TESTING_MATH
extern double far *dx1, far *dy1;
extern long far *lx1, far *ly1;
#define dShiftx dx1[row]
#define dShifty dy1[col]
#define lShiftx lx1[row]
#define lShifty ly1[col]
#else
#define dShiftx 0.0
#define dShifty 0.0
#define lShiftx 0L
#define lShifty 0L
#endif
extern _LCMPLX lold, lnew;
extern char FormName[];
extern VOIDFARPTR typespecific_workarea;
#define LastSqr v[4].a
static char far * far ErrStrings[] = { /* TIW 03-31-91 added far */
"Should be an Argument",
"Should be an Operator",
"')' needs a matching '('",
"Need more ')'",
"Undefined Operator",
"Undefined Function",
"More than one ','",
"Table overflow"
};
unsigned SkipWhiteSpace(char *Str) {
unsigned n, Done;
for(Done = n = 0; !Done; n++) {
switch(Str[n]) {
case ' ':
case '\t':
case '\n':
case '\r':
break;
default:
Done = 1;
}
}
return(n - 1);
}
/* Random number code, MCP 11-21-91 */
unsigned long NewRandNum(void)
{
return(RandNum = ((RandNum << 15) + rand15()) ^ RandNum);
}
void lRandom(void)
{
v[7].a.l.x = NewRandNum() >> (32 - bitshift);
v[7].a.l.y = NewRandNum() >> (32 - bitshift);
}
void dRandom(void)
{
long x, y;
/* Use the same algorithm as for fixed math so that they will generate
the same fractals when the srand() function is used. */
x = NewRandNum() >> (32 - bitshift);
y = NewRandNum() >> (32 - bitshift);
v[7].a.d.x = ((double)x / (1L << bitshift));
v[7].a.d.y = ((double)y / (1L << bitshift));
}
#ifndef XFRACT
void mRandom(void)
{
long x, y;
/* Use the same algorithm as for fixed math so that they will generate
the same fractals when the srand() function is used. */
x = NewRandNum() >> (32 - bitshift);
y = NewRandNum() >> (32 - bitshift);
v[7].a.m.x = *fg2MP(x, bitshift);
v[7].a.m.y = *fg2MP(y, bitshift);
}
#endif
void SetRandFnct(void)
{
unsigned Seed;
if(!SetRandom)
RandNum = Arg1->l.x ^ Arg1->l.y;
Seed = (unsigned)RandNum ^ (unsigned)(RandNum >> 16);
srand(Seed);
SetRandom = 1;
/* Clear out the seed */
NewRandNum();
NewRandNum();
NewRandNum();
}
void RandomSeed(void)
{
time_t ltime;
/* Use the current time to randomize the random number sequence. */
time(<ime);
srand((unsigned int)ltime);
NewRandNum();
NewRandNum();
NewRandNum();
Randomized = 1;
}
#ifndef XFRACT
void lStkSRand(void)
{
SetRandFnct();
lRandom();
Arg1->l = v[7].a.l;
}
#endif
#ifndef XFRACT
void mStkSRand(void)
{
Arg1->l.x = Arg1->m.x.Mant ^ (long)Arg1->m.x.Exp;
Arg1->l.y = Arg1->m.y.Mant ^ (long)Arg1->m.y.Exp;
SetRandFnct();
mRandom();
Arg1->m = v[7].a.m;
}
#endif
void dStkSRand(void)
{
Arg1->l.x = (long)(Arg1->d.x * (1L << bitshift));
Arg1->l.y = (long)(Arg1->d.y * (1L << bitshift));
SetRandFnct();
dRandom();
Arg1->d = v[7].a.d;
}
void (*StkSRand)(void) = dStkSRand;
void dStkAbs(void) {
Arg1->d.x = fabs(Arg1->d.x);
Arg1->d.y = fabs(Arg1->d.y);
}
#ifndef XFRACT
void mStkAbs(void) {
if(Arg1->m.x.Exp < 0)
Arg1->m.x.Exp = -Arg1->m.x.Exp;
if(Arg1->m.y.Exp < 0)
Arg1->m.y.Exp = -Arg1->m.y.Exp;
}
void lStkAbs(void) {
Arg1->l.x = labs(Arg1->l.x);
Arg1->l.y = labs(Arg1->l.y);
}
#endif
void (*StkAbs)(void) = dStkAbs;
void dStkSqr(void) {
LastSqr.d.x = Arg1->d.x * Arg1->d.x;
LastSqr.d.y = Arg1->d.y * Arg1->d.y;
Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0;
Arg1->d.x = LastSqr.d.x - LastSqr.d.y;
LastSqr.d.x += LastSqr.d.y;
LastSqr.d.y = 0;
}
#ifndef XFRACT
void mStkSqr(void) {
LastSqr.m.x = *MPmul(Arg1->m.x, Arg1->m.x);
LastSqr.m.y = *MPmul(Arg1->m.y, Arg1->m.y);
Arg1->m.y = *MPmul(Arg1->m.x, Arg1->m.y);
Arg1->m.y.Exp++;
Arg1->m.x = *MPsub(LastSqr.m.x, LastSqr.m.y);
LastSqr.m.x = *MPadd(LastSqr.m.x, LastSqr.m.y);
LastSqr.m.y.Mant = (long)(LastSqr.m.y.Exp = 0);
}
void lStkSqr(void) {
LastSqr.l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift);
LastSqr.l.y = multiply(Arg1->l.y, Arg1->l.y, bitshift);
Arg1->l.y = multiply(Arg1->l.x, Arg1->l.y, bitshift) << 1;
Arg1->l.x = LastSqr.l.x - LastSqr.l.y;
LastSqr.l.x += LastSqr.l.y;
LastSqr.l.y = 0L;
}
#endif
void (*StkSqr)(void) = dStkSqr;
void dStkAdd(void) {
Arg2->d.x += Arg1->d.x;
Arg2->d.y += Arg1->d.y;
Arg1--;
Arg2--;
}
#ifndef XFRACT
void mStkAdd(void) {
Arg2->m = MPCadd(Arg2->m, Arg1->m);
Arg1--;
Arg2--;
}
void lStkAdd(void) {
Arg2->l.x += Arg1->l.x;
Arg2->l.y += Arg1->l.y;